//reduce 方法

function reduce(array, fn, initdata) {
  if (array.length) {
    let pre = initdata !== undefined ? initdata : array[0];
    let i = initdata !== undefined ? 0 : 1;
    for (; i < array.length; i++) {
      pre = fn(pre, array[i]);
    }
    return pre;
  } else {
    //数组为空，函数不执行
    if (initdata) {
      return initdata;
    } else {
      throw new Error('erro');
    }
  }
}

//数组扁平化

function flat(arr){
  let newarr=[]
   function flated(array){
    array.forEach(item=>{
      if(Array.isArray(item)){
        flated(item)
      }else{
        newarr.push(item)
      }
    })
  }
  flated(arr)
  return newarr;
}

// console.log(flat([1,[2,3,[4,[5,[6]]]]]))

// 函数柯里化

function curry(fn) {
  return function curried(...args) {
    if (args.length < fn.length) {
      return function () {
        return curried(...args.concat([...arguments]));
      };
    }
    return fn(...args);
  };
}

//函数组合

function compose(...args) {
  //接受函数作为参数
  return function (value) {
    //反转数组使从右向左执行函数
    return args.reverse().reduce(function (pre, fn) {
      //将上一个函数的执行结果交给当前函数
      return fn(pre);
    }, value);
  };
}

//generator自执行器 co模块

function co(generator) {
  let g = generator();

  function handleResolve(result) {
    if (result.done) return;
    let val = result.value;
    if (val instanceof Promise) { //yiled后面是promise
      val.then(
        data => {
          handleResolve(g.next(data));
        },
        err => g.throw(err)
      );
    }else{
      handleResolve(g.next(val));
    }
  }
  handleResolve(g.next());
}

setTimeout(() => {
  console.log(1);
  Promise.resolve().then(() => {
    console.log(2);
  });
});
setTimeout(() => {
  console.log(3);
  Promise.resolve().then(() => {
    console.log(4);
  });
});
// 1，2，3，4

setTimeout(() => {
  console.log(1);
  setTimeout(() => {
    console.log(2);
  });
});
setTimeout(() => {
  console.log(3);
  Promise.resolve().then(() => {
    console.log(4);
  });
});
// 1，3，2，4
